﻿Imports System.ComponentModel.DataAnnotations.Schema

Partial Public Class Script
    <NotMapped>
    Public Property Parameters As Hashtable
    <NotMapped>
    Public Property ForceDebug As Boolean = False
    <NotMapped>
    Public Property ForceVerbose As Boolean = False
    <NotMapped>
    Public Property ForceStopOnError As Boolean = False

    Private ScriptHistoryId As Int64

#Region "iCronTask"
    Private _CronGuid As New Guid
    Private WithEvents pse As PSExecuter.PSExecute

    Public ReadOnly Property AllowConcurrent As Boolean Implements iCronTask.AllowConcurrent
        Get
            Return Not Me.SingleInstance
        End Get
    End Property

    Public ReadOnly Property CronGuid As Guid Implements iCronTask.CronGuid
        Get
            Return Me._CronGuid
        End Get
    End Property

    Public ReadOnly Property CronName As String Implements iCronTask.CronName
        Get
            Return String.Format("{0}:{1}", "Script", Me.Name)
        End Get
    End Property

    Public ReadOnly Property CronStatus As CronStatus Implements iCronTask.CronStatus
        Get
            If Me.pse IsNot Nothing Then
                Return Service.CronStatus.NotInitialized
            Else
                Return pse.Status
            End If
        End Get
    End Property

    Public Async Sub Execute() Implements iCronTask.Execute
        If Me.Parameters IsNot Nothing AndAlso Me.Parameters.Count > 1 Then
            pse = New PSExecuter.PSExecute(Me.Code, Me.Parameters, Me.ForceVerbose, Me.ForceDebug, Me.ForceStopOnError)
        Else
            pse = New PSExecuter.PSExecute(Me.Code, Me.ForceVerbose, Me.ForceDebug, Me.ForceStopOnError)
        End If

        HistoryStart()
        Try
            Await pse.ExecuteAsync()
        Catch ex As Exception
            Dim msg As String = String.Format("Error in {0} [{1}]:{2}{3}", Me.CronName, Me.CronGuid, Environment.NewLine, ex.ToString)
            Log.LogMessage(msg, LogTypes.Error)
        End Try
        HistoryEnd()
    End Sub

    Public Sub Cancel() Implements iCronTask.Cancel
        pse.CancelExecute()
    End Sub

    Public Event Canceled(sender As iCronTask) Implements iCronTask.Canceled
    Public Event Completed(sender As iCronTask) Implements iCronTask.Completed

    Private Async Sub pse_DataGenerated(sender As Object, e As PSExecuter.PSExecuteStreamData) Handles pse.DataGenerated
        Using db As New PowerShellCronContext
            db.ScriptResults.Add(New ScriptResult With {.ScriptHistoryId = Me.ScriptHistoryId,
                                                        .Generated = e.DataGenerated,
                                                        .Type = e.Source.ToString,
                                                        .Message = e.Message})
            Await db.SaveChangesAsync()
        End Using
    End Sub

    Private Sub HistoryStart()
        Using db As New PowerShellCronContext
            Dim sh As New ScriptHistory With {.CronGuid = Me.CronGuid,
                                              .ScriptId = Me.ScriptId,
                                              .StartDTO = DateTimeOffset.Now,
                                              .Status = "Executing",
                                              .Parameters = Me.Parameters}
            db.ScriptHistories.Add(sh)
            db.SaveChanges()
            Me.ScriptHistoryId = sh.ScriptHistoryId
        End Using
    End Sub

    Private Sub HistoryEnd()
        Using db As New PowerShellCronContext
            Dim sh As ScriptHistory = db.ScriptHistories.Find(Me.ScriptHistoryId)
            sh.EndDTO = DateTimeOffset.Now
            sh.Status = Me.pse.Status.ToString
            db.SaveChanges()
        End Using
    End Sub
#End Region
End Class
